當我們想要使用php的內容,基本上在wordpress上編輯是會被直接轉化成esc_html的,我們這邊定義的wordpress編輯係指在wordpress的後台加入的內容,而如我們要讓動態資料載入到我們的wordpress 編輯內容之中,我們可以使用shortcode來達成,藉由輸入參數來讓它出現多采多姿得樣子。
在原生的系統上,我們可以使用的就有六種(不包含外掛提供的),而以下是個部分,單一使用都很基礎,可以在節錄的介紹中看見,我們就快速的展示:
使用add_shortcode其實非常容易,與其他更加簡潔,只需要加入有唯一性的$tag,然後帶入你要回傳的template,這樣即可以顯示,而另外的刪除shortcode則是與先前無異,找到地方及可以刪除,而如果我們的shortcode需要加入更多的參數,只需要在回傳的函式中加入即可,add_shortcode是不用加入的,可以看見shortcode的handler中間三個是如何處理,來做相對應的條件顯示。
我們使用woocommerce來當範例,請大家去安裝一下,學好電商不吃虧XD我們建立一個產品的項目(card),woocommerce有提供[products]可以直接顯示,可是如果我們只是想要簡單的顯示,圖片、標題以及價錢呢?
add_action( 'init', 'go_ranger_shortcode' );
function go_ranger_shortcode(){
  add_shortcode('ranger_shoot','ranger_shoot_template');
}
function ranger_shoot_template($atts = [], $content = null, $tag = ''){
  $user_parms = shortcode_atts( array(
		'product_id' => '0'
	), $atts );
  get_search_content($user_parms['product_id']);
}
function get_search_content($product_id){
  $product = wc_get_product( $product_id );
  $image = wp_get_attachment_image_src( get_post_thumbnail_id( $product_id ), 'single-post-thumbnail' );?>
  <img src="<?php  echo $image[0]; ?>" >
  <span> <?php echo $product->get_name(); ?></span>
  <span> <?php echo $product->get_price(); ?></span>
  <?php
}
如此我們就可以做一個簡單的產品顯示卡片,而想要加入的可以有更多的彈性,而在woocommerce中的global $product這些取得,因為不太熟悉所以都是使用wc_get_product來代替,除非是進到特定頁面才有辦法取得那些get_title的資料,所以在使用還是明確點較為恰當,那我們就來做我們員工的貢獻表了。
add_action( 'init', 'go_ranger_shortcode' );
function go_ranger_shortcode(){
  add_shortcode('ranger_shoot','ranger_milestone_template');
}
function ranger_milestone_template($atts = [], $content = null, $tag = ''){
  global $current_user; 
  if($current_user){
    go_ranger_user_collaborate(get_current_user_id());
  } else go_ranger_default_template();
}
function go_ranger_user_collaborate($user__ID ) {
  // $level也可以用來檢查權限
  $level = get_user_meta( $user__ID, 'user_level', true );
  if (  empty( $level ) ) {
        go_ranger_default_template();
        return;
  }
  $posts = get_posts( [ 'numberposts' => -1 ] ); 
  $posts_count = count_user_posts( $user->ID );?>
  <h2>貢獻里程碑</h2>
  <table class="form-table">
    <tr>
      <th><label for="go_ranger-favorite-post">等級</label></th>
      <td><?php echo esc_html($level) ?></td>
    </tr>
		<tr>
			<th><label for="go_ranger-favorite-post">Favorite Post</label></th>
      <td>
        <ol>
					<?php foreach ( $posts as $post ) {
						printf(
							'<li>%s</li>',
							esc_html( $post->post_title )
						);
					} ?>
        <ol/>
        </br>
				<span class="description">你已經完成了<?php echo esc_html($posts_count) ?>書本上傳了!</span>
			</td>
		</tr>
	</table>
 <?php }
 function go_ranger_default_template(){
   echo "看來你不是屬於我們的一員。";
 }
現在我們就可以使用[ranger_shoot]就可以顯示我們的貢獻表了,當時還在朦朧時看到了shortcode寫作,不過讓人為之一亮的shortcode寫法,當時很迷這個東西,我幾乎所有的東西都用shortcode來代替,不過在更深入了解content post之後,對於模板的切換有著更深入的理解,回頭看來,shortcode真的是方便,但不要將使用的情境搞混才是最好的。
而shortcode唯一的問題就是比較慢,然而我們不可能因為效能的關係,就放棄這個動態增加的用法,在wordpress的開發之中,最大的問題就是評估,才不會讓你的網站效率慢又ux糟糕,而另外有個其他的應用,是將shortcode加入widget之中,這其實非常容易,只需要在你的程式碼中加入add_filter( 'widget_text', 'do_shortcode' );,這樣即可在點選custom HTML的widget之中加入加入你要的內容,比如說像無名小站人氣累積(以暴漏年齡)之類的,或是建成class來加入register_widget,也是非常好用的啦,下面節錄簡單的使用來做應用!
class Level_system_Widgets extends WP_Widget {
    public function __construct(){
        $widget_ops = array( 
            'classname' => 'level_system_widget',
            'description' => 'Level System Widget',
        );
        parent::__construct( 'level_system_widget', 'Level System Widget', $widget_ops );
    }
    public function widget( $args, $instance ) {
        echo $args['before_widget'];
        if ( ! empty( $instance['title'] ) ) {
            echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
        }
        echo esc_html__( 'Hello, World!', 'text_domain' );
        echo $args['after_widget'];
    }   
    public function form( $instance ) {
        $title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'text_domain' );
    ?>
    <p>
    <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label> 
    <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
    </p>
    <?php 
    }
    public function update( $new_instance, $old_instance ) {
        $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
    return $instance;
    }
}
add_action('widgets_init', create_function('', 'return register_widget("Level_system_Widgets");'));
shortcode就到此告一段落,雖然寫這個是寫了就可以在看到改變,但我覺得外掛開發的核心,還是得先著重在後台中,option設定及編排,以系統資料的設定複雜度,是足以應付前端的一些基礎需求的,在wordpress中最困難的不是寫程式,而是你不知道寫了一個功能後,是不是原生就已經有提供這一項了,做白工是不舒服的。
wordpress - shortcode
wordpress - do_shortcode
 How to Add Audio Files and Create Playlists in WordPress
Using WP_Query to pull and display WooCommerce Products
in woocommerce, is there a shortcode/page to view all orders?
How to make my custom widget appear within WordPress widgets? Plugin development